#ifndef __ANIMATIONGRAPHDIALOG2_H__
#define __ANIMATIONGRAPHDIALOG2_H__

#pragma once

#include "FlatFrameCtrl.h"

#include "AnimationGraphStateEditor_2.h"
#include "AnimationGraphStateQuery_2.h"
#include "AnimationGraphTester_2.h"
#include "..\HyperGraphView.h"
#include "AnimationGraphPreviewDialog_2.h"
#include "AnimationGraphPreviewManager_2.h"
#include "AnimationGraph2_DefaultsDialog.h"
#include "AnimationGraphStateParams_2.h"
#include "../LMGEditor/AnimationsListView.h"
#include "../LMGEditor/IAnimationNameSelectionChangedListener.h"

#define ANIMATION_GRAPH_NAME "Animation Graph"
#define ANIMATION_GRAPH_VER "1.5"

class CAnimationGraphDialog2;




class CAGHyperGraphView2: public CHyperGraphView
{
	DECLARE_DYNCREATE(CAGHyperGraphView2)
protected:
	virtual void ShowContextMenu( CPoint point, CHyperNode* pNode );
	virtual void UpdateTooltip( CHyperNode* pNode, CHyperNodePort* pPort ) {}
};




class CAnimationGraphListCtrl2 : public CTreeCtrl
{
public:
	CAnimationGraphListCtrl2( CAnimationGraphDialog2 * pParent ) : m_pParent(pParent) {}

	virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
	void ReloadStates();
	void ReloadViews();
	void ReloadInputs();
	void ReloadModifiers();
	void SelectItemByName( const CString& name );

	typedef std::pair< CString, int > TNameIcon;

private:
	void AddList( std::vector< TNameIcon >& values );
	bool IsInputUsed(CAGInput2Ptr pInput);

private:
	CAnimationGraphDialog2 * m_pParent;
	CImageList m_imageList;

protected:
	DECLARE_MESSAGE_MAP()
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};




class CAnimationGraph2_GenericDetails : public CDialog
{
	//DECLARE_DYNCREATE( CAnimationGraph2_GenericDetails );

public:
	CAnimationGraph2_GenericDetails() {}

	enum { IDD = IDD_AG2_DETAILS_PANE };

protected:
	//DECLARE_MESSAGE_MAP()
 
	virtual void OnOK() {}
	virtual void OnCancel() {}
};




//////////////////////////////////////////////////////////////////////////
// CAnimationGraphDialog2
//////////////////////////////////////////////////////////////////////////

class CAnimationGraph2;
typedef _smart_ptr<CAnimationGraph2> CAnimationGraph2Ptr;


class CAnimationGraphDialog2
	: public CXTPFrameWnd
	, public IAnimationGraphListener2
	, public IHyperGraphListener
	, public IAnimationNameSelectionChangedListener
	, ICharacterChangeListener
{
	friend class CAGHyperGraphView2;

	DECLARE_DYNCREATE(CAnimationGraphDialog2);
public:
	static void RegisterViewClass();

	CAnimationGraphDialog2();
	~CAnimationGraphDialog2();

	BOOL Create( DWORD dwStyle,const RECT& rect,CWnd* pParentWnd );

	void OnHyperGraphEvent( IHyperNode * pNode, EHyperGraphEvent event );

	void OnModifierNodeEvent( CAGNodeBase2* pBaseNode, EHyperGraphEvent event );
	void OnStateNodeEvent( EHyperGraphEvent event );
	void OnLinkEdit( CHyperEdge * pEdge );

	void OnStateEvent( EAGStateEvent2 evt, CAGState2Ptr pState );
	void OnViewEvent( EAGViewEvent2, CAGView2Ptr pView );
	void OnInputEvent( EAGInputEvent2, CAGInput2Ptr pInput );
	void OnModifierEvent( EAG2ModifierEvent evt, CAG2ModifierBasePtr pModifier );

	void OnGraphModified();
	void OnGraphIslandReport();
	void OnGraphSpeedReport();
	void OnGraphBadCALReport();
	void OnGraphBadNullNodeReport();
	void OnGraphDeadInputReport();
	void OnGraphTransitionLengthReport();
	void OnGraphMatchSpeeds();
	void OnGraphOrphanNodesReport();

	//! Menu entry Settings->Default Settings
	//! Opens the dialog window and updates the character file afterwards if needed
	void OnGraphDefaultSettingsDialog();

	//! Opens About box in the menu
	void OnGraphVersionInfo();

	CAnimationGraph2Ptr GetAnimationGraph();

	void SetParamsDeclaration( CParamsDeclaration2 * pParamsDeclaration )
	{
		m_stateParamsCtrl.SetParamsDeclaration( pParamsDeclaration );
	}
	void OnStateParamSelChanged();
	void SelectState(const CString& stateName, bool bIgnoreDependencies = true);

	bool ResetParameterization();

	bool AddParamValue( const char* param, const char* value ) { return m_stateEditor.AddParamValue( param, value ); }
	bool DeleteParamValue( const char* param, const char* value ) { return m_stateEditor.DeleteParamValue( param, value ); }
	bool RenameParamValue( const char* param, const char* oldValue, const char* newValue ) { return m_stateEditor.RenameParamValue( param, oldValue, newValue ); }

	bool AddParameter( const CString& name ) { return m_stateEditor.AddParameter( name ); }
	bool DeleteParameter( const CString& name ) { return m_stateEditor.DeleteParameter( name ); }
	bool RenameParameter( const CString& oldName, const CString& newName ) { return m_stateEditor.RenameParameter( oldName, newName ); }

	int GetExcludeFromGraph() { return m_vStates.size() != 1 ? -1 : m_vStates[0]->GetExcludeFromGraph(); }
	void SetExcludeFromGraph( bool bExclude ) { if ( m_vStates.size() == 1 ) m_vStates[0]->SetExcludeFromGraph( bExclude ); }
	const CAGView2Ptr GetSelectedView() const { return m_pView; }

	bool SetGraph(const char* graphName);
	enum { IDD = IDD_TRACKVIEWDIALOG };

	CXTPDockingPaneManager* GetDockingPaneManager() { return &m_paneManager; }
/*
	CXTPDockingPane* GetNodeDetailsPane() 
	{ 
		return m_pNodeDetailsPane; 
	}
*/
	void ReloadInputs()
	{
		m_inputListCtrl.ReloadInputs();
	}

	CWnd* GetNodeDetailsParent() 
	{ 
		return &m_genericNodeDetails;
	}

	// IAnimationNameSelectionChangedListener
	virtual void AnimationNameSelectionChanged( const CString& currentSelectedAnimationName );
	// ~IAnimationNameSelectionChangedListener

protected:
	DECLARE_MESSAGE_MAP()

	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual BOOL OnInitDialog();
	afx_msg void OnDestroy();
	afx_msg void OnFileNew();
	afx_msg void OnFileOpen();
	afx_msg void OnFileSave();
	afx_msg void OnFileSaveAs();
	afx_msg void OnDelete();
	afx_msg void OnGraphAddState();
	afx_msg void OnGraphAddView();
	afx_msg void OnGraphAddInput();
	afx_msg void OnGraphAddModifier( UINT nID );
	afx_msg void OnGraphCreateAnimation();
	afx_msg void OnGraphTrial();
	afx_msg void OnAGLinkMappingChanged();
	afx_msg BOOL OnViewPane( UINT cmdID );
	afx_msg void OnViewPaneStateQuery();
	afx_msg void OnStateListSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnStateListClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnViewListSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnViewListClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnInputListSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnInputListClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnModifierListSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg LRESULT OnDockingPaneNotify(WPARAM wParam, LPARAM lParam);
	afx_msg LRESULT OnTaskPanelNotify(WPARAM wParam, LPARAM lParam);    

	afx_msg void OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnModifierListBeginDrag(NMHDR* pNMHDR, LRESULT* pResult);
	
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnIconSizeChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnUpdateIconSizeUI(CCmdUI* pCmdUI);
	afx_msg void OnDisplayIconsChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnUpdateDisplayIconsUI(CCmdUI* pCmdUI);
	afx_msg void OnDisplayPreviewChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnUpdateDisplayPreviewUI(CCmdUI* pCmdUI);
	afx_msg void OnContextMenu( CWnd* pWnd, CPoint pos );

	afx_msg void OnCustomize();
	afx_msg void OnExportShortcuts();
	afx_msg void OnImportShortcuts();

private:
	enum EItemType
	{
		eIT_State,
		eIT_View,
		eIT_Input,
		eIT_Root,
		eIT_Error
	};

	void SetGraph( CAnimationGraph2Ptr pGraph );
	void SetActiveView( CAGView2Ptr pView );
	void SetActiveState( CAGState2Ptr pState );
	void SetActiveStates( std::vector< CAGState2Ptr > vStates );
	void ViewReport( const CString& report );

	void UpdateTitle();
	void UpdateGraphMenu();
	void ReadDisplayedIconSize();
	void EnableIcons(bool enableIcons);
	void EnablePreview(bool enablePreview);

	void AnimationStatePopupMenu( CAGState2* pState, CWnd* wnd, CPoint &pos );
	void ModifierStatePopupMenu( CAG2ModifierBasePtr pModifier, CWnd* wnd, CPoint &pos );
	void ViewPopupMenu( CAGView2Ptr pView, CWnd* wnd, CPoint &pos );
	void InputPopupMenu( CAGInput2Ptr pInput, CWnd* wnd, CPoint &pos );

	void RegisterConsoleVariables();

	// ICharacterChangeListener
	virtual void OnCharacterChanged();

	int m_nBlockSelChanged;

	CXTPDockingPaneManager m_paneManager;

	CAnimationGraph2Ptr m_pGraph;
	CAGView2Ptr m_pView;
	std::vector< CAGState2Ptr > m_vStates;
	CFlatFramedCtrl2< CAnimationGraphListCtrl2 > m_stateListCtrl;
	CFlatFramedCtrl2< CAnimationGraphListCtrl2 > m_viewListCtrl;
	CFlatFramedCtrl2< CAnimationGraphListCtrl2 > m_inputListCtrl;
	CFlatFramedCtrl2< CAnimationGraphListCtrl2 > m_modifierListCtrl;
	CAnimationGraphStateEditor2 m_stateEditor;
	CFlatFramedCtrl2< CAnimationGraphStateParamsPanel2 > m_stateParamsCtrl;
	CFlatFramedCtrl2< CAnimationGraph2_GenericDetails > m_genericNodeDetails;
	CAnimationGraphTester2 m_tester;
	CAnimationGraphStateQuery2 m_stateQuery;
	_smart_ptr<CHyperGraph> m_pViewHypergraph;
	CAGHyperGraphView2* m_view;
	CImageList * m_pDragImage;
	CString m_dragNodeClass;
	uint m_dragModifierId;
	CXTPStatusBar m_statusBar;
	CAnimationImageManager2Ptr m_pCAnimationImageManager;
	CAnimationGraphPreviewDialog2 m_previewDialog;
	CAnimationGraphPreviewManager2 m_previewManager;
	CAnimationGraph2DefaultsDialog m_defaultsDialog;
	CRollupCtrl m_rollupCtrl;
	CXTPToolBar* m_wndToolBar;
	CAnimationsListView m_animationListView;

	// Pane for the various node details to attach their interfaces to display upon
	CXTPDockingPane* m_pNodeDetailsPane;

	typedef std::pair<int, int> IconSize;
	typedef std::vector<IconSize> IconSizeList;
	IconSizeList m_iconSizes;

	ICVar* m_displayedIconSize;
	ICVar* m_enableIcons;
	ICVar* m_preview;
	HACCEL m_hAccelerators;
};

#endif
